package com.mbengue.corp.artisan.dao.impl;

import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.util.Assert;

import com.mbengue.corp.artisan.dao.ClientDao;
import com.mbengue.corp.artisan.modele.Client;

public class ClientDaoImpl implements ClientDao {
  private static Logger logger = Logger.getLogger(ClientDao.class);
  private HibernateTemplate hbTemplate;

  public void setSessionFactory(SessionFactory sessionFactory) {
    this.hbTemplate = new HibernateTemplate(sessionFactory);
  }

  @Override
  public void ajouterClient(Client client) throws DataAccessException {
    logger.info("Ajout d'un nouveau client: " + client);
    this.hbTemplate.saveOrUpdate(client);
  }

  @Override
  public void modifierClient(Client client) throws DataAccessException {
    logger.info("Mise a jour du client: " + client);
    this.hbTemplate.update(client);
  }

  @Override
  public void supprimerClient(Client client) throws DataAccessException {
    logger.info("Client a supprimer: " + client);
    this.hbTemplate.delete(client);
  }

  @SuppressWarnings("unchecked")
  @Override
  public List<Client> tousLesClients() throws DataAccessException {
    logger.info("Recupere tous les clients");
    DetachedCriteria criteria = DetachedCriteria.forClass(Client.class);
    return this.hbTemplate.findByCriteria(criteria);
  }

  @SuppressWarnings("unchecked")
  @Override
  public Client trouverClientParId(long idClient) throws DataAccessException {
    logger.info("Trouve le client qui a cet identifiant: " + idClient);
    DetachedCriteria criteria = DetachedCriteria.forClass(Client.class);
    criteria.add(Restrictions.eq("clientId", idClient));
    List<Client> clients = this.hbTemplate.findByCriteria(criteria);
    Assert.isTrue(clients.size() <= 1);

    if (clients.size() == 0) {
      return null;
    }
    return clients.get(0);
  }

  @SuppressWarnings("unchecked")
  @Override
  public List<Client> trouverClientParNomPrenom(String nom, String prenom) throws DataAccessException {
    logger.info("Trouve les clients dont le nom et/ou prenom est: (" + nom + " " + prenom + ")");
    return this.hbTemplate.findByNamedQuery("trouverClientParNom", new String[] { nom, prenom });
  }

  @SuppressWarnings("unchecked")
  @Override
  public Client trouverClientParNumeroTelephone(String telephone) throws DataAccessException {
    logger.info("Trouve le client dont le numero de telephone est : " + telephone);
    List<Client> clients = this.hbTemplate.findByNamedQuery("trouverClientParNumeroTelephone", telephone);
    Assert.isTrue(clients.size() <= 1);

    if (clients.size() == 0) {
      return null;
    }
    return clients.get(0);
  }

  @SuppressWarnings("unchecked")
  @Override
  public List<String> tousLesNomsClients() throws DataAccessException {
    logger.info("Retourne une concaténation des nom et prenom de chaque client ...");
    return this.hbTemplate.find("select c.fullName from Client c");
  }

  @SuppressWarnings("unchecked")
  @Override
  public List<Client> trouverClientParNomEtPrenom(String nom, String prenom) {
    logger.info("Retrouve tous les clients dont les nom et prenom sont: " + nom + " " + prenom);
    return this.hbTemplate.findByNamedQuery("trouverClientNomEtPrenom", new String[] { nom, prenom });
  }
}
